module PNEngine
  class Token < ActiveRecord::Base
    include Resource::InstanceMethods
    extend Resource::ClassMethods
    
    belongs_to :place
    validates_presence_of :place
    
    def combinations
      Combinations.instance.find(:token => self)
    end
        
    belongs_to :case
    serialize :cached_locators, Hash
    
    before_save :eliminate_xml_version

    belongs_to :user
    
    before_update :strip_value
    def strip_value
      self.value = self.value.strip if !self.value.blank?
    end
    
    # Deeper cloning for tokens
    def clone
      t = super
      t.case = self.case
      t.place = self.place
      return t
    end
	
    def eliminate_xml_version
      #TODO a nicer remove of xml version!!
      self.value.gsub!('<?xml version="1.0"?>', "") if self.value
    end
    
    #Returns all attributes of token specified by locators
    def values
      if Merb::Config[:locator_caching]
        if self.cached_locators.nil?
          self.cached_locators = collect_locators
          save!
        end
        return self.cached_locators
      else
        return collect_locators
      end
    end
	
    #sets one specific locator at token to new value. Don't forget to save token afterwards
    def set_locator(locator, val)
      loc = place.locators.select{|loc| loc.name == locator}.first
      raise "No locator found for writing value in token" if loc.nil?
      self.value = loc.write(value, val)
      self.cached_locators = nil
      return self.value
    end

    before_create :create_new_case
    def create_new_case
      self.case ||= Case.new
    end
    
    private
    # used by values method, collecting all attributes from locators
    def collect_locators
      vals = {}
      place.locators.collect do |locator|
        vals[locator.name] = locator.evaluate(value)
      end
      vals
    end
    
  end
end
